package com.dream.cgomall.service.impl;

import com.dream.cgomall.configura.factory.StatusFactory;
import com.dream.cgomall.dao.CgoGoodAttributeOneLevelDao;
import com.dream.cgomall.dao.CgoGoodAttributeTwoLevelDao;
import com.dream.cgomall.dao.CgoOrderDao;
import com.dream.cgomall.dao.CgoOrderGoodsDao;
import com.dream.cgomall.dto.ShoppingDTO;
import com.dream.cgomall.emnus.OrderStatusEnum;
import com.dream.cgomall.entity.CgoGoods;
import com.dream.cgomall.entity.CgoOrder;
import com.dream.cgomall.entity.CgoOrderGoods;
import com.dream.cgomall.service.CgoGoodsService;
import com.dream.cgomall.service.CgoOrderService;
import com.dream.cgomall.util.OrderCodeUtil;
import com.dream.cgomall.DO.OrderDo;
import com.dream.cgomall.util.RedisUtil;
import com.dream.cgomall.vo.OrderGoodsVo;
import com.dream.cgomall.vo.OrderVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

@Service
public class CgoOrderServiceImpl implements CgoOrderService {
    @Autowired
    private CgoOrderDao cgoOrderDao;
    @Autowired
    private CgoOrderGoodsDao cgoOrderGoodsDao;
    @Autowired
    private  RedisUtil redisUtil;
    @Autowired
    private CgoGoodsService cgoGoodsService;
    @Autowired
    private CgoGoodAttributeOneLevelDao oneLevelDao;
    @Autowired
    private CgoGoodAttributeTwoLevelDao twoLevelDao;
    @Autowired
    private CgoOrderServiceImpl cgoOrderService;
    @Autowired
    private OrderCodeUtil  orderCodeUtil;
    public List<ShoppingDTO> findShoppings(List<Integer> list){
        return cgoOrderDao.findShopping(list);
    }
    static List<CgoOrderGoods> add(List<ShoppingDTO> list ){
        List<CgoOrderGoods> cgoOrderGoodsList = new ArrayList<>();
        for (int i = 0; i<list.size(); i++){
            CgoOrderGoods cgoOrderGoods = new CgoOrderGoods();
            cgoOrderGoods.setGoodsId(list.get(i).getGoodsID());
            cgoOrderGoods.setGoodsName(list.get(i).getGoodsName());
            cgoOrderGoods.setGoodsAttr(list.get(i).getNorm());
            cgoOrderGoods.setGoodsQuantity(list.get(i).getQuantity());
            cgoOrderGoods.setGoodsPrice(list.get(i).getPrice());
            cgoOrderGoodsList.add(cgoOrderGoods);
        }
        return cgoOrderGoodsList;
    }
    //生成订单
    @Override
    @Transactional
    public Long addToOrder(OrderDo orderDo) throws Exception {
        if (orderDo==null){
            return 0L;
        }
        int i = 0;
        CgoOrder cgoOrder = new CgoOrder();
            //将VO对象中的值注入到order中
            List<ShoppingDTO> list = Arrays.asList(orderDo.getList());
            //将第一个参数赋值给第二个参数
            List<CgoOrderGoods> add = add(list);
            
            BeanUtils.copyProperties(orderDo, cgoOrder);
            long orderId =orderCodeUtil.nextId();
            cgoOrder.setOrderId(orderId);
            LocalDateTime ldt = LocalDateTime.now();
            cgoOrder.setCreateTime(ldt);
            i = cgoOrderDao.insertOrder(cgoOrder);
            for (int j=0;j<add.size();j++){
                CgoOrderGoods cgoOrderGoods = add.get(j);
                if (i !=0){
                    cgoOrderGoods.setOrderId(cgoOrder.getId());
                }
                //减少库存
                int goodsId = cgoOrderGoods.getGoodsId();
                String[] arr=cgoOrderGoods.getGoodsAttr().split(",");
                int quantity = -(cgoOrderGoods.getGoodsQuantity());
                cgoOrderService.ModifyInventory(goodsId,arr[0],arr[1],quantity);
            }
            cgoOrderGoodsDao.insert(add);
            redisUtil.setRedis("order:"+orderId,cgoOrder);
            redisUtil.setRedis("order:"+orderId+"EX",cgoOrder,16L);
            System.out.println(cgoOrder.getOrderId());
        return cgoOrder.getId();
    }
    public Integer updateOrderStatus(Long id){
        return cgoOrderDao.updateOrderStatus(id, OrderStatusEnum.FORMAL_EVENT.status);
    }
    //查询用户所有订单
    public List<OrderVo> findAllOrder(Integer statusId,Integer userId){
        List<CgoOrder> cgoOrders = cgoOrderDao.findOrderByUserIdAndStatus(statusId,userId);
        List<OrderVo> vo = new ArrayList<>();
        for (int i = 0; i<cgoOrders.size();i++){
            CgoOrder cgoOrder = cgoOrders.get(i);
            OrderVo orderVo = new OrderVo();
            orderVo.setId(cgoOrder.getId());
            String status = StatusFactory.status(cgoOrder.getStatus());
            orderVo.setStatusID(cgoOrder.getStatus());
            orderVo.setActualPrice(cgoOrder.getActualPrice());
            orderVo.setStatus(status);
            orderVo.setCreateTime(cgoOrder.getCreateTime());
            List<CgoOrderGoods> l = cgoOrderGoodsDao.findGoodsByOrderId(cgoOrder.getId());
            List<OrderGoodsVo> t = new ArrayList<>() ;
            for (CgoOrderGoods cgoOrderGoods : l) {
                OrderGoodsVo orderGoodsVo = new OrderGoodsVo();
                BeanUtils.copyProperties(cgoOrderGoods, orderGoodsVo);
                CgoGoods goods = cgoGoodsService.findGoods(cgoOrderGoods.getGoodsId());
                orderGoodsVo.setPic(goods.getPic());

                t.add(orderGoodsVo);
            }
            orderVo.setCgoOrderGoodsList(t);
            vo.add(orderVo);
        }
        return vo;
    }
    public CgoOrder finOrder(Integer id){
       return cgoOrderDao.findOrderByOrderId(id);
    }
    public List<CgoOrderGoods> findshoopDetails(Long id){
        List<CgoOrderGoods> goodsByOrderId = cgoOrderGoodsDao.findGoodsByOrderId(id);
        return goodsByOrderId;
    }
    //减少库存
    @Transactional
    public void ModifyInventory(Integer goodsId,String context,String context2,int nums) throws Exception {
        int logoId = oneLevelDao.findLogoId(goodsId, context);
        if (twoLevelDao.findGoodsNums(goodsId,logoId,context2) >= nums){
            oneLevelDao.reduceNumById(goodsId,nums);
            twoLevelDao.updateNums(goodsId,logoId,context2,nums);
        }else {
            throw new Exception();
        }
    }

}
